using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using ComponentFactory.Krypton.Toolkit;
using Xeml.Manager;
using Xeml.Document;
using Xeml.Document.Contracts;
using Xeml.Document.Ontologies.OBO;

namespace Xid.Controls
{
    public partial class AddOntologyWizard : ComponentFactory.Krypton.Toolkit.KryptonForm
    {

        private OntologyHandlerResource _handlerResource;
        private IDocument _xemlDoc;
        public OntologyHandlerResource AddedHandlerResource { get; private set; }
        public AddOntologyWizard(IDocument xemlDoc)
        {
            _xemlDoc = xemlDoc;
            InitializeComponent();
            kryptonNavigator1.SelectedIndex = 0;
            _handlerResource = new OntologyHandlerResource("temp");
            textBoxAlias.DataBindings.Add("Text", _handlerResource, "NameSpaceAlias");
            textBoxOntology.DataBindings.Add("Text", _handlerResource, "Location");

            // init the ontologyType combobox
            comboBoxOntologyType.DataSource = Enum.GetValues(typeof(OntologyType)).Cast<OntologyType>().Select(x => new
            {
                Value = (int)x,
                Key = x.ToString()
            }).ToList();
            comboBoxOntologyType.DisplayMember = "Key";
            comboBoxOntologyType.ValueMember = "Value";

            kryptonNavigator1.SelectedPageChanged += new EventHandler(kryptonNavigator1_SelectedPageChanged);
            handlerCollectionBindingSource.CurrentChanged += new EventHandler(handlerCollectionBindingSource_CurrentChanged);
            comboBoxOntologyType.SelectedIndexChanged += new EventHandler(comboBoxOntologyType_SelectedIndexChanged);

            // trigger the SelectedIndexChanged event
            comboBoxOntologyType.SelectedIndex = 1;
            comboBoxOntologyType.SelectedIndex = 0;
        }

        void handlerCollectionBindingSource_CurrentChanged(object sender, EventArgs e)
        {
            IOntologyHandler io = handlerCollectionBindingSource.Current as IOntologyHandler;
            textBoxHandlerUri.DataBindings.Clear();
            textBoxPublisher.DataBindings.Clear();
            textBoxVersion.DataBindings.Clear();
            textBoxDescription.DataBindings.Clear();
            textBoxAuthor.DataBindings.Clear();

            textBoxHandlerUri.Text = "-";
            textBoxPublisher.Text = "-";
            textBoxVersion.Text = "-";
            textBoxDescription.Text = "-";
            textBoxAuthor.Text = "-";

            if (io != null)
            {
                textBoxHandlerUri.DataBindings.Add("Text", io, "Uri");
                textBoxPublisher.DataBindings.Add("Text", io, "Publisher");
                textBoxVersion.DataBindings.Add("Text", io, "Version");
                textBoxDescription.DataBindings.Add("Text", io, "Description");
                textBoxAuthor.DataBindings.Add("Text", io, "Author");
            }
        }

        void comboBoxOntologyType_SelectedIndexChanged(object sender, EventArgs e)
        {
            IList<IOntologyHandler> list = OntologyManager.Instance.Values.Where(x => x.OntologyType == (OntologyType)comboBoxOntologyType.SelectedValue).ToList();
            handlerCollectionBindingSource.DataSource = list;
        }

        void kryptonNavigator1_SelectedPageChanged(object sender, EventArgs e)
        {
            kryptonButtonBackToHandlerPage.Enabled = kryptonNavigator1.SelectedIndex != 0;
            if (kryptonNavigator1.SelectedIndex == 2)
            {
                kryptonButtonNextToFinish.Text = "Finish";
            }
            else
            {
                kryptonButtonNextToFinish.Text = "Next";
            }
        }

        private void kryptonButtonNextToFinish_Click(object sender, EventArgs e)
        {
            if (kryptonNavigator1.SelectedIndex < 2)
            {
                kryptonNavigator1.PerformNextAction();
            }
            else
            {
                this.ValidateChildren();
                bool valid = true;
                kryptonLabelError.Visible = false;

                if (string.IsNullOrEmpty(textBoxAlias.Text))
                {
                    errorProvider1.SetError(textBoxAlias, "The alias can't be empty.");
                    kryptonLabelError.Text = "The alias can't be empty.";
                    kryptonLabelError.Visible = true;
                    return;
                }
                else
                {
                    errorProvider1.SetError(textBoxAlias, "");
                }
                if (string.IsNullOrEmpty(textBoxOntology.Text))
                {
                    errorProvider1.SetError(textBoxOntology, "The ontology can't be empty.");
                    kryptonLabelError.Text = "The ontology can't be empty.";
                    kryptonLabelError.Visible = true;
                    return;
                }
                else
                {
                    errorProvider1.SetError(textBoxOntology, "");
                }

                IOntologyHandler io = handlerCollectionBindingSource.Current as IOntologyHandler;
                if (io != null)
                {
                    if (_xemlDoc.DocumentResources.Contains(_handlerResource.NameSpaceAlias, io.OntologyType))
                    {
                        errorProvider1.SetError(textBoxAlias, "The alias already exist.");
                        valid = false;
                    }
                    else
                    {
                        try
                        {
                            OntologyHandlerResource ohr = _xemlDoc.DocumentResources.Add(io.Uri, _handlerResource.NameSpaceAlias, _handlerResource.Location, (OntologyType)comboBoxOntologyType.SelectedValue, true);
                            if (ohr.ComponentState != ComponentLoadState.Loaded)
                            {
                                valid = false;
                                kryptonLabelError.Text = "Unable to load handler. Component state is: " + ohr.ComponentState.ToString();
                                kryptonLabelError.Visible = true;
                            }

                            try
                            {
                                this.Enabled = false;
                                Cursor.Current = Cursors.WaitCursor;
                                ohr.LoadOntology();
                            }
                            finally
                            {
                                this.Enabled = true;
                                Cursor.Current = Cursors.Default;
                            }

                            if (ohr.Handler.OntologyLoadState != OntologyLoadState.Loaded)
                            {
                                errorProvider1.SetError(textBoxOntology, ohr.Handler.OntologyLoadMessage);
                                valid = false;
                            }
                            else
                            {
                                AddedHandlerResource = ohr;
                            }
                        }
                        catch (Exception ex)
                        {
                            Microsoft.SqlServer.MessageBox.ExceptionMessageBox box = new Microsoft.SqlServer.MessageBox.ExceptionMessageBox(ex);
                            box.Show(this);
                        }
                    }
                    if (valid)
                    {
                        DialogResult = DialogResult.OK;
                        //  _xemlDoc.DocumentResources.Remove(_handlerResource);
                        this.Close();
                    }

                    #region old stuff

                    //if (io.OntologyType == OntologyType.Environment)
                    //{
                    //    if (_xemlDoc.DocumentResources.EnvironmentOntologyHandler.Contains(_handlerResource.NameSpaceAlias))
                    //    {
                    //        errorProvider1.SetError(textBoxAlias, "The alias already exist.");
                    //        valid = false;
                    //    }
                    //    else
                    //    {
                    //        _handlerResource.LoadComponent(io.Uri);
                    //        if (_handlerResource.ComponentState != ComponentLoadState.Loaded)
                    //        {
                    //            valid = false;
                    //            kryptonLabelError.Text = "Unable to load handler. Component state is: " + _handlerResource.ComponentState.ToString();
                    //            kryptonLabelError.Visible = true;
                    //        }
                    //        this.Enabled = false;
                    //        Cursor.Current = Cursors.WaitCursor;
                    //        _handlerResource.LoadOntology();
                    //        this.Enabled = true;
                    //        Cursor.Current = Cursors.Default;

                    //        if (_handlerResource.Handler.OntologyLoadState != OntologyLoadState.Loaded)
                    //        {
                    //            errorProvider1.SetError(textBoxOntology, _handlerResource.Handler.OntologyLoadMessage);
                    //            valid = false;
                    //        }

                    //    }
                    //    if (valid)
                    //    {
                    //        _xemlDoc.DocumentResources.EnvironmentOntologyHandler.Add(_handlerResource);
                    //        this.Close();
                    //    }
                    //}

                    //if (io.OntologyType == OntologyType.OrganismStructure)
                    //{
                    //    if (_xemlDoc.DocumentResources.OrganismStructureOntologyHandler.Contains(_handlerResource.NameSpaceAlias))
                    //    {
                    //        errorProvider1.SetError(textBoxAlias, "The alias already exist.");
                    //        valid = false;
                    //    }
                    //    else
                    //    {
                    //        _handlerResource.LoadComponent(io.Uri);
                    //        if (_handlerResource.ComponentState != ComponentLoadState.Loaded)
                    //        {
                    //            valid = false;
                    //            kryptonLabelError.Text = "Unable to load handler. Component state is: " + _handlerResource.ComponentState.ToString();
                    //            kryptonLabelError.Visible = true;
                    //        }
                    //        this.Enabled = false;
                    //        Cursor.Current = Cursors.WaitCursor;
                    //        _handlerResource.LoadOntology();
                    //        this.Enabled = true;
                    //        Cursor.Current = Cursors.Default;

                    //        if (valid && _handlerResource.Handler.OntologyLoadState != OntologyLoadState.Loaded)
                    //        {
                    //            errorProvider1.SetError(textBoxOntology, "Unable to load ontology, load message is:" + _handlerResource.Handler.OntologyLoadMessage);
                    //            valid = false;
                    //        }

                    //    }
                    //    if (valid)
                    //    {
                    //        _xemlDoc.DocumentResources.OrganismStructureOntologyHandler.Add(_handlerResource);
                    //        this.Close();
                    //    }
                    //}

                    //if (io.OntologyType == OntologyType.Developmental)
                    //{
                    //    if (_xemlDoc.DocumentResources.DevelopmentalOntologyHandler.Contains(_handlerResource.NameSpaceAlias))
                    //    {
                    //        errorProvider1.SetError(textBoxAlias, "The alias already exist.");
                    //        valid = false;
                    //    }
                    //    else
                    //    {
                    //        _handlerResource.LoadComponent(io.Uri);
                    //        if (_handlerResource.ComponentState != ComponentLoadState.Loaded)
                    //        {
                    //            valid = false;
                    //            kryptonLabelError.Text = "Unable to load handler. Component state is: " + _handlerResource.ComponentState.ToString();
                    //            kryptonLabelError.Visible = true;
                    //        }
                    //        this.Enabled = false;
                    //        Cursor.Current = Cursors.WaitCursor;
                    //        _handlerResource.LoadOntology();
                    //        this.Enabled = true;
                    //        Cursor.Current = Cursors.Default;

                    //        if (valid && _handlerResource.Handler.OntologyLoadState != OntologyLoadState.Loaded)
                    //        {
                    //            errorProvider1.SetError(textBoxOntology, "Unable to load ontology, load message is:" + _handlerResource.Handler.OntologyLoadMessage);
                    //            valid = false;
                    //        }

                    //    }
                    //    if (valid)
                    //    {
                    //        _xemlDoc.DocumentResources.OrganismStructureOntologyHandler.Add(_handlerResource);
                    //        this.Close();
                    //    }

                    //}

                    //if (io.OntologyType == OntologyType.Positioning)
                    //{
                    //    if (_xemlDoc.DocumentResources.PositioningOntologyHandler.Contains(_handlerResource.NameSpaceAlias))
                    //    {
                    //        errorProvider1.SetError(textBoxAlias, "The alias already exist.");
                    //        valid = false;
                    //    }
                    //    else
                    //    {
                    //        _handlerResource.LoadComponent(io.Uri);
                    //        if (_handlerResource.ComponentState != ComponentLoadState.Loaded)
                    //        {
                    //            valid = false;
                    //            kryptonLabelError.Text = "Unable to load handler. Component state is: " + _handlerResource.ComponentState.ToString();
                    //            kryptonLabelError.Visible = true;
                    //        }
                    //        this.Enabled = false;
                    //        Cursor.Current = Cursors.WaitCursor;
                    //        _handlerResource.LoadOntology();
                    //        this.Enabled = true;
                    //        Cursor.Current = Cursors.Default;

                    //        if (valid && _handlerResource.Handler.OntologyLoadState != OntologyLoadState.Loaded)
                    //        {
                    //            errorProvider1.SetError(textBoxOntology, "Unable to load ontology, load message is:" + _handlerResource.Handler.OntologyLoadMessage);
                    //            valid = false;
                    //        }

                    //    }
                    //    if (valid)
                    //    {
                    //        _xemlDoc.DocumentResources.PositioningOntologyHandler.Add(_handlerResource);
                    //        this.Close();
                    //    }

                    //}
#endregion
                }
                else
                {
                    kryptonLabelError.Text = "No handler selected";
                    kryptonLabelError.Visible = true;
                    valid = false;
                }
            }
        }

        private void kryptonButtonBackToHandlerPage_Click(object sender, EventArgs e)
        {
            kryptonNavigator1.PerformPreviousAction();
        }

        private void kryptonButtonCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        public void AfterOntologyLoaded(Object sender, LoadStateChangedEventArgs e)
        {
        }
    }

    internal class HandlerCollection : List<IXemlComponent>
    {
    }
}